package com.dhcc.cdc.task;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dhcc.cdc.busi.dao.CdcBsEmrStructMapper;
import com.dhcc.cdc.busi.entity.CdcEmrEntity;
import com.dhcc.cdc.busi.entity.CdcEpisodeEntity;
import com.dhcc.cdc.busi.entity.CdcExaminateEntity;
import com.dhcc.cdc.busi.service.*;
import com.dhcc.cdc.sys.cache.config.CdcConfigCache;
import com.dhcc.cdc.util.KettleUtil;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.DateUtil;
import org.pentaho.di.core.exception.KettleException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service("CdcAutoTask")
public class CdcAutoTask {
    @Autowired
    private ICdcEpisodeService cdcEpisodeService;
    @Autowired
    private ICdcEmrService cdcEmrService;
    @Autowired
    private ICdcBsEmrStructService cdcBsEmrStructService;
    @Autowired
    private ICdcExaminationService cdcExaminationService;
    @Autowired
    private ICdcBsExamStructService cdcBsExamStructService;
    double all = 1;
    Double cur = (double) 0;
    public void analysisData(){
        String nlpUrl = CdcConfigCache.me().getValueByKey("SDS", "SDAnalysisServer");
        // 获取在院患者
        //多线程版
        ExecutorService analysisService = Executors.newFixedThreadPool(10);//分析数据线程池
        List<CdcEpisodeEntity> episodeList = cdcEpisodeService.selectList(new EntityWrapper<CdcEpisodeEntity>().gt("code_date", DateUtil.getAfterDayDate("-1")));
        all = episodeList.size() * 2;
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisode : episodeList) {
            analysisService.execute(new analysisEmrData(cdcEpisode.getId()));
            analysisService.execute(new analysisExamData(cdcEpisode.getId()));
        }
        analysisService.shutdown();
    }

    public void analysisEmrData(Map<String, Object> params) {
        Wrapper<CdcEpisodeEntity> wrapper = new EntityWrapper<>();
        if (CommonUtil.isNotEmpty(params.get("patientId"))) {
            wrapper.eq("id", params.get("patientId"));
        }
        if (CommonUtil.isNotEmpty(params.get("startDate"))) {
            wrapper.gt("dish_date", params.get("startDate"));
        }
        if (CommonUtil.isNotEmpty(params.get("endDate"))) {
            wrapper.lt("dish_date", params.get("endDate"));
        }
        //多线程版
        ExecutorService analysisEmrService = Executors.newFixedThreadPool(10);//分析数据线程池
        List<CdcEpisodeEntity> episodeList = cdcEpisodeService.selectList(wrapper);
        all = episodeList.size();
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisode : episodeList) {
            analysisEmrService.execute(new analysisEmrData(cdcEpisode.getId()));
        }
        analysisEmrService.shutdown();
    }

    public class analysisEmrData extends Thread {
        private Long episodeId;

        public analysisEmrData(Long episodeId) {
            this.episodeId = episodeId;
        }

        public void run() {
            try {
                //消费
                AnalysisEmrDataMain(episodeId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void AnalysisEmrDataMain(Long episodeId) throws Exception {
        String nlpUrl = CdcConfigCache.me().getValueByKey("SDS", "SDAnalysisServer");
        // 获取病历数据
        List<CdcEmrEntity> emrList = cdcEmrService.selectList(new EntityWrapper<CdcEmrEntity>().eq("episode_id", episodeId));
        cdcBsEmrStructService.emrStructByNLP(nlpUrl, emrList);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }

    public void analysisExamData(Map<String, Object> params) {
        Wrapper<CdcEpisodeEntity> wrapper = new EntityWrapper<>();
        if (CommonUtil.isNotEmpty(params.get("patientId"))) {
            wrapper.eq("id", params.get("patientId"));
        }
        if (CommonUtil.isNotEmpty(params.get("startDate"))) {
            wrapper.gt("dish_date", params.get("startDate"));
        }
        if (CommonUtil.isNotEmpty(params.get("endDate"))) {
            wrapper.lt("dish_date", params.get("endDate"));
        }
        //多线程版
        ExecutorService analysisExamService = Executors.newFixedThreadPool(10);//分析数据线程池
        List<CdcEpisodeEntity> episodeList = cdcEpisodeService.selectList(wrapper);
        all = episodeList.size();
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisode : episodeList) {
            analysisExamService.execute(new analysisExamData(cdcEpisode.getId()));
        }
        analysisExamService.shutdown();
    }

    public class analysisExamData extends Thread {
        private Long episodeId;

        public analysisExamData(Long episodeId) {
            this.episodeId = episodeId;
        }

        public void run() {
            try {
                //消费
                AnalysisExamDataMain(episodeId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void AnalysisExamDataMain(Long episodeId) throws Exception {
        String nlpUrl = CdcConfigCache.me().getValueByKey("SDS", "SDAnalysisServer");
        // 获取病历数据
        List<CdcExaminateEntity> examList = cdcExaminationService.selectList(new EntityWrapper<CdcExaminateEntity>().eq("episode_id", episodeId));
        cdcBsExamStructService.examStructByNLP(nlpUrl, examList);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }


    public Map<String, Object> getProcess() {
        Map<String, Object> state = new HashMap<String, Object>();
        if (all == 0) {//没有获取到数据
            state.put("v", "100");//值
            state.put("i", "none");//信息
        } else {
            if (cur < all) {//进行中
                DecimalFormat df = new DecimalFormat("0.00");
                state.put("v", df.format(cur / all * 100));//值
                state.put("i", "doing");//信息
            } else {
                state.put("v", "100");//值
                state.put("i", "done");//信息
            }
        }
        return state;
    }
}
